home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / gamesrc / bg_src / bg_user2.c < prev    next >
C/C++ Source or Header  |  1993-03-07  |  12KB  |  361 lines

  1. /*
  2.  *
  3.  *                     B  G  _  U  S  E  R  2 .  C
  4.  * BG.EXE user interaction file, the second of two,
  5.  * this version 30th May 1992.
  6.  *
  7.  */
  8.  
  9. #include <stdlib.h>
  10. #include <stdio.h>
  11. #include <conio.h>
  12. #include <time.h>
  13. #include "bg.h"
  14. #include "mousy.h"
  15.  
  16. /***************************************************************************/
  17.  
  18. char User_Selects_Move (Dice_t*    Dice,     /* The dice the user threw */
  19.                         Layout_t   User_Old, /* Users current situation */
  20.                         Layout_t   Comp_Old, /* Computers current situation */
  21.                         Transit_t* User_Tr,  /* How the user moved */
  22.                         Transit_t* Comp_Tr,  /* Computers new situation */
  23.                         Player_t   Player)   /* The User */
  24. /*
  25. PURPOSE: To get the user to move the pieces.
  26. NOTES:   1) If an error is made or the user hits ESCAPE then we restart
  27.          the whole process, from moving the very first piece.
  28.          2) We return F10_KEY if the user wants to abandon the game.
  29. */
  30. {
  31.     Dice_t Pool ;       /* Local copy of input dice */
  32.     short Start,End ;   /* Points selected by the user */
  33.     ushort Dice_Used ;  /* Index of dice used (0..3) */
  34.  
  35.     short N_Ends ;               /* N legal endps poss from start selected */
  36.     short Ends [MAX_MOVES] ;     /* List of endps possible */
  37.     short D_I_List [MAX_MOVES] ; /* List of indices into dice pool */
  38.     short End_Index ;            /* Index into above two lists */
  39.  
  40.     Transit_t Loc_User ;  /* Local copies of input layouts transformed... */
  41.     Transit_t Loc_Comp ;  /* ...gradually to output transits */
  42.  
  43.     short Moves_Made ;    /* Moves done so far */
  44.     short Moves_To_Make ; /* User MUST make this number of moves */
  45.     boolean Moved ;
  46.     char Key ;
  47.  
  48.     Init_Human_Vars (&Moves_Made,&Pool,Dice, &Loc_User,&Loc_Comp,
  49.                      User_Old,Comp_Old) ;
  50.  
  51.     /* Get the computer to tell us how many moves to make */
  52.     Select_Best_Move (Dice,User_Old,Comp_Old,User_Tr,
  53.                       Comp_Tr,Player,Legalest) ;
  54.  
  55.     Moves_To_Make = User_Tr->N_Moves ;
  56.     if (Moves_To_Make == 0) {
  57.         /* You are totally blocked */
  58.         Pool.N_Vals = 0 ;
  59.         Show_Dice_List (&Pool) ;
  60.         if (Player == WHITE_PLAYER) {
  61.         Print_Message (W_NOGO_MSG) ;
  62.         } else {
  63.         Print_Message (B_NOGO_MSG) ;
  64.         }
  65.         Seconds_Delay (3) ;
  66.         Clear_Help_Line () ;
  67.         return (NUL) ; /* No keys hit by the user */
  68.     }
  69.  
  70.     while ((Moves_Made < Moves_To_Make) &&
  71.            (Won(Loc_User.Layout,Loc_Comp.Layout)) == NO_WIN) {
  72.     Show_Dice_List (&Pool) ;
  73.     Moved = FALSE ;
  74.     Print_Message (SEL_STA_MSG) ;
  75.     Start = Get_User_Point_Choice (&Key,Player,OUT_ARROW_SHP) ;
  76.         if (Key == F10_KEY) {
  77.             return (F10_KEY) ;
  78.         } else if (Key == F9_KEY) {
  79.             User_Error_Exit () ;
  80.         }
  81.         if (Key != ESC_KEY) {
  82.             N_Ends = Legal_Start (&Loc_User,&Loc_Comp, /* Situation now */
  83.                                   &Pool,               /* Dice to use */
  84.                                   Start,               /* Start point */
  85.                                   Ends,D_I_List);      /* List of possibles */
  86.             if (N_Ends > 0) {
  87.                 Print_Message (SEL_END_MSG) ;
  88.                 End = Get_User_Point_Choice (&Key,Player,IN_ARROW_SHP) ;
  89.                 if (Key == F10_KEY) {
  90.                     return (F10_KEY) ;
  91.                 }
  92.                 if (Key != ESC_KEY) {
  93.                     End_Index = Legal_End (End,Ends,N_Ends) ;
  94.                     if (End_Index != NOT_VALID_END) {
  95.                         Dice_Used = D_I_List [End_Index] ;
  96.                         Execute_Move ((char)Start,
  97.                                       Pool.Values[Dice_Used],
  98.                                       &Loc_User,&Loc_Comp) ;
  99.                         Deplete_Dice_Pool (&Pool,Dice_Used) ;
  100.                         Show_Dice_List (&Pool) ;
  101.                         Update_User_Move (Loc_User.Layout,
  102.                                           Loc_Comp.Layout,
  103.                                           Player) ;
  104.                         Moves_Made++ ;
  105.                         #if DRODBAR
  106.                         Show_Threat (Loc_User.Layout,Loc_Comp.Layout,End) ;
  107.                         #endif
  108.                         Moved = TRUE ; /* Assume he wants to do it */
  109.                         if (Moves_Made == Moves_To_Make) {
  110.                             Print_Message (CLK_GO_MSG) ;
  111.                             (void)Get_User_Point_Choice (&Key,Player,QUESTION_SHP) ;
  112.                             if (Key == F10_KEY) {
  113.                                 return (Key) ;
  114.                             } else if (Key == ESC_KEY) {
  115.                                 Moved = FALSE ;
  116.                             }
  117.                         }
  118.                     } else {
  119.                         Print_Message (CANT_END_MSG) ;
  120.                         Seconds_Delay(2) ;
  121.                     }
  122.                 }
  123.             } else {
  124.                 Print_Message (CANT_START_MSG) ;
  125.                 Seconds_Delay(1) ;
  126.             }
  127.         }
  128.         if (!Moved) {
  129.             /* The user has to start again, from scratch
  130.             Copy_Dice (&Pool,Dice) ;
  131.             Init_Transit (&Loc_User,User_Old) ;
  132.             Init_Transit (&Loc_Comp,Comp_Old) ;
  133.             Moves_Made = 0 ; */
  134.             Init_Human_Vars (&Moves_Made,&Pool,Dice, &Loc_User,&Loc_Comp,
  135.                              User_Old,Comp_Old) ;
  136.             Update_User_Move (Loc_User.Layout,Loc_Comp.Layout,Player) ;
  137.         }
  138.         Clear_Help_Line () ;
  139.     } /* end of while () */
  140.  
  141.     Copy_Transit (User_Tr,&Loc_User) ;
  142.     Copy_Transit (Comp_Tr,&Loc_Comp) ;
  143.  
  144.     /* Show an empty dice list */
  145.     Pool.N_Vals = 0 ;
  146.     Show_Dice_List (&Pool) ;
  147.  
  148.     return (NUL) ; /* No keys hit */
  149. }
  150.  
  151. /***************************************************************************/
  152.  
  153. short Get_User_Point_Choice (char* Key, Player_t Player, short Shape_Code)
  154. /*
  155. PURPOSE: To get the user to select a point or to hit the escape key.
  156. If the user hits a key then we return with Key set, else
  157. we return the point selected by the user (using mouse or keyboard).
  158. */
  159. {
  160.     short User_Input,Mx,My,G_Row,G_Col,Hot_X,Hot_Y ;
  161.  
  162.     if (Shape_Code == NORMAL_SHP) {
  163.     Hot_X = 0 ;
  164.     Hot_Y = 0 ;
  165.     } else {
  166.     Hot_X = 7 ;
  167.     Hot_Y = 7 ;
  168.     }
  169.  
  170.     Show_Mouse_Cursor () ;
  171.     Set_Cursor_Shape (Shape_Code,Hot_X,Hot_Y) ;
  172.  
  173.     (*Key) = NUL ;
  174.     do {
  175.     User_Input = Get_Mouse_Or_Key (&Mx,&My) ;
  176.     if (User_Input & KEY_BIT) {
  177.         if ((User_Input & CHAR_MASK) == ESC_KEY) {
  178.         Hide_Mouse_Cursor () ;
  179.         (*Key) = ESC_KEY ;
  180.         return (0) ;
  181.         }
  182.     } else if (User_Input & FUN_BIT) {
  183.         if ((User_Input & CHAR_MASK) == F10_KEY) {
  184.         Hide_Mouse_Cursor () ;
  185.         (*Key) = F10_KEY ;
  186.                 return (0) ;
  187.             }
  188.             if ((User_Input & CHAR_MASK) == F9_KEY) {
  189.                 Hide_Mouse_Cursor () ;
  190.                 (*Key) = F9_KEY ;
  191.                 return (0) ;
  192.             }
  193.         }
  194.     } while (!(User_Input & (LEFT_BIT | RIGHT_BIT))) ;
  195.     Hide_Mouse_Cursor () ;
  196.  
  197.     /* Mx, My now contain the mouse coords */
  198.     if (Pixel_To_Grid (&G_Col,&G_Row,Mx,My)) {
  199.         return (Grid_To_Point (G_Col,G_Row,Player)) ;
  200.     } else {
  201.         return (0) ;
  202.     }
  203. }
  204.  
  205. /***************************************************************************/
  206.  
  207. short Legal_Start (Transit_t* Me, Transit_t* Him, /* These are the...  */
  208.                    Dice_t* Dice, short Point,     /* ...inputs.        */
  209.                    short End_Points[MAX_MOVES], /* List of end points possible */
  210.                    short D_I_List[MAX_MOVES])   /* Dice used for the end point */
  211. /*
  212. PURPOSE: Given the inputs we return the number of moves we can make with
  213.          this dice along with with End_Points and D_I_List.
  214. */
  215. {
  216.     short epi,d ;    /* End Point Index */
  217.  
  218.     epi = 0 ;
  219.  
  220.     for (d = 0 ; d < Dice->N_Vals ; d++) {
  221.         if (Can_Move (Point,Dice->Values[d],Me->Layout,Him->Layout)) {
  222.             End_Points[epi] = Point+Dice->Values[d] ;
  223.             if (End_Points[epi] > HOME_I) {
  224.                 End_Points[epi] = HOME_I ;
  225.             }
  226.             D_I_List [epi] = d ;
  227.             epi++ ;
  228.         }
  229.     }
  230.     return (epi) ;
  231. }
  232.  
  233. /***************************************************************************/
  234.  
  235. short Legal_End (short Point, short List[MAX_MOVES], short N_Ends)
  236. /*
  237. PURPOSE: The user wants to move to Point, if it's in the list we return
  238.          it's index, else we return NOT_VALID_END
  239. */
  240. {
  241.     short p ;
  242.  
  243.     p = 0 ;
  244.     while (p < N_Ends) {
  245.         if (Point == List[p]) {
  246.             return (p) ;
  247.         }
  248.         p++ ;
  249.     }
  250.     return (NOT_VALID_END) ;
  251. }
  252.  
  253. /***************************************************************************/
  254.  
  255. void Update_User_Move (Layout_t User, Layout_t Comp, Player_t Player)
  256. /*
  257. PURPOSE: To redraw the board showing the users positions, whether he
  258.          is white or black.
  259. */
  260. {
  261.     if (Player == BLACK_PLAYER) {
  262.         Draw_Board_Quick (User,Comp) ;
  263.     } else {
  264.         Draw_Board_Quick (Comp,User) ;
  265.     }
  266. }
  267.  
  268. /***************************************************************************/
  269. #if DRODBAR
  270. void Show_Threat (Layout_t Me, Layout_t Him, short Point)
  271. /*
  272. PURPOSE: To print the threat of him to me at this point.
  273. */
  274. {
  275.     short Threat ;
  276.  
  277.     Side_Text (THREAT_ROW,0,"THREAT:    ",WHITE) ;
  278.     Threat = Get_Probs (Me,Him,Point,FALSE) ;
  279.     Side_Number (THREAT_ROW,9,Threat,3,WHITE) ;
  280. }
  281. #endif
  282. /***************************************************************************/
  283.  
  284. void Init_Human_Vars (short*  Moves_Made, Dice_t* Pool, Dice_t* Dice,
  285.                       Transit_t* Loc_User, Transit_t* Loc_Comp,
  286.                       Layout_t   User_Old, Layout_t   Comp_Old)
  287. /*
  288. PURPOSE: To prepare the above vars for a new user move, starting from scratch.
  289. */
  290. {
  291.  
  292.     (*Moves_Made) = 0 ;        /* He has not yet moved */
  293.     Copy_Dice (Pool,Dice) ;    /* So he has all initial dice values */
  294.     Init_Transit (Loc_User,User_Old) ; /* Init the transits from... */
  295.     Init_Transit (Loc_Comp,Comp_Old) ; /* ...what he starts with.   */
  296. }
  297.  
  298. /***************************************************************************/
  299.  
  300. void User_Error_Exit (void)
  301. /*
  302. PURPOSE: To let the user send a message about something he has noticed
  303. has gone wrong before abandoning the game. The error message is the
  304. last thing typed in the file BG??.REC
  305. */
  306. {
  307.     extern char Globerr [GERR_LEN] ;
  308.     short i ;
  309.     int  ch ;
  310.  
  311.     Clear_Help_Line () ;
  312.     Help_Text (0,"TYPE ERROR DESCRIPTION:",WHITE) ;
  313.     i = 0 ;
  314.     Globerr [i] = NUL ;
  315.     while ((ch = getch ()) != ENTER_KEY) {
  316.         if ((ch == BACK_KEY) && (i > 0)) {
  317.             i-- ;
  318.             Globerr[i] = NUL ;
  319.         } else if (i < (GERR_LEN-1)) {
  320.             Globerr[i] = (char)ch ;
  321.             printf ("%c",ch) ;
  322.             i++ ;
  323.             Globerr[i] = NUL ;
  324.         }
  325.     }
  326.     Error_Exit ("USER HIT F9") ;
  327. }
  328.  
  329. /***************************************************************************/
  330.  
  331. short Key_And_Delay (short Seconds)
  332. /*
  333. PURPOSE: To wait Seconds or until a key is hit. We return the key hit
  334. or zero if we timed out first.
  335. */
  336.  
  337. {
  338.     char   Key_0 ;
  339.     short  Key_Code ;
  340.     time_t Now,Then ;
  341.  
  342.     (void)time (&Then) ;
  343.     do {
  344.         if (kbhit()) {
  345.             Key_0 = (char)getch () ;
  346.             if (Key_0 == FUN_PREFIX) {
  347.                 Key_Code = FUN_BIT | getch () ;
  348.             } else {
  349.                 Key_Code = KEY_BIT | Key_0 ;
  350.             }
  351.             return (Key_Code) ;
  352.         }
  353.         (void)time(&Now) ;
  354.     } while ((Now - Then) < Seconds) ;
  355.  
  356.     return (0) ;
  357. }
  358.  
  359. /***************************************************************************/
  360.  
  361.